package org.lcc.Service.impl;

import org.lcc.Service.TestResultsService;
import org.lcc.config.KeyLoader;
import org.lcc.mapper.TestResultsMapper;
import org.lcc.model.VO.*;
import org.lcc.model.dto.GetExamScoreListDto;
import org.lcc.model.entity.BusinessException;
import org.lcc.model.entity.StudentMistakeEntity;
import org.lcc.util.RSAUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TestResultsServiceImpl implements TestResultsService {
    // RSA私钥
    private PrivateKey privateKey;
    @Value("${rsa.privateKey}")
    private String privateKeyBase64;
    
    @Autowired
    private TestResultsMapper testResultsMapper;
    // 密码加密器，用于校验密码
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    // 初始化RSA密钥
    @PostConstruct
    public void initKeys() throws Exception {
        privateKey = KeyLoader.loadPrivateKey(privateKeyBase64);
    }
    @Override
    public Map<String, Object> getExamScoreList(GetExamScoreListDto getExamScoreListDto) {
        Map<String, Object> result = new HashMap<>();
        // 计算offset值
        int pageNum = getExamScoreListDto.getPageNum(); // 当前页码
        int pageSize = getExamScoreListDto.getPageSize(); // 每页大小
        int offset = (pageNum - 1) * pageSize; // 计算偏移量
        // 查询考试成绩列表
        List<Map<String, Object>> examScoreList = testResultsMapper.getExamScoreList(
                getExamScoreListDto.getStartTime(),
                getExamScoreListDto.getEndTime(),
                getExamScoreListDto.getSearchText(),
                offset,
                pageSize
        );
        System.out.println("examScoreList"+examScoreList);

        // 查询总记录数
        Integer total = testResultsMapper.getExamScoreListCount(
                getExamScoreListDto.getStartTime(),
                getExamScoreListDto.getEndTime(),
                getExamScoreListDto.getSearchText()
        );

        // 转换为VO对象
        List<ExamScoreVO> examScoreVOList = new ArrayList<>();
        for (Map<String, Object> map : examScoreList) {
            ExamScoreVO examScoreVO = new ExamScoreVO();
            examScoreVO.setExamId(Long.valueOf(map.get("examId").toString()));
            examScoreVO.setExamName((String) map.get("examName"));
            examScoreVO.setParticipants(Long.valueOf(map.get("participants").toString()) );
            examScoreVO.setQualified(Long.valueOf(map.get("qualified").toString()) );
            examScoreVO.setPassRate((BigDecimal) map.get("passRate"));
            examScoreVO.setAvgScore((BigDecimal) map.get("avgScore"));
            examScoreVO.setHighestScore(Long.valueOf(map.get("highestScore").toString()));
            examScoreVO.setLowestScore(Long.valueOf (map.get("lowestScore").toString()));
            examScoreVO.setCorrectRate((BigDecimal) map.get("correctRate"));
            examScoreVO.setScoreRate((BigDecimal) map.get("scoreRate"));
            examScoreVOList.add(examScoreVO);
        }

        result.put("data", examScoreVOList);
        result.put("total", total);

        return result;
    }

    @Override
    public ExamScoreDetailVO getExamScoreDetail(Integer examId) {
        // 获取考试基本信息
        Map<String, Object> examInfo = testResultsMapper.getExamInfo(examId);
        System.out.println("examInfo"+examInfo);
        if (examInfo == null) {
            return null;
        }

        // 获取考试统计数据
        Map<String, Object> examStats = testResultsMapper.getExamStats(examId);
        //遍历打印再控制台上
        for (Map.Entry<String, Object> entry : examStats.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        // 获取分数分布
        Map<String, BigDecimal> scoreDistribution = testResultsMapper.getScoreDistribution(examId);
        //遍历打印
        for (Map.Entry<String, BigDecimal> entry : scoreDistribution.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        // 组装数据
        ExamScoreDetailVO detailVO = new ExamScoreDetailVO();
        detailVO.setExamId(Long.valueOf(examInfo.get("examId") != null ? examInfo.get("examId").toString() : "0"));
        detailVO.setExamName((String) examInfo.get("examName"));
        detailVO.setSubject((String) examInfo.get("subject"));
        detailVO.setStartTime((String) examInfo.get("startTime"));
        detailVO.setEndTime((String) examInfo.get("endTime"));

        // 安全地将 totalScore 和 passScore 转换为 BigDecimal
        detailVO.setTotalScore(examInfo.get("totalScore") != null ?
                new BigDecimal(examInfo.get("totalScore").toString()) : BigDecimal.ZERO);
        detailVO.setPassScore(examInfo.get("passScore") != null ?
                new BigDecimal(examInfo.get("passScore").toString()) : BigDecimal.ZERO);

        // 安全地将统计数据转换为 BigDecimal
        detailVO.setParticipants(examStats.get("participants") != null ?
                new BigDecimal(examStats.get("participants").toString()) : BigDecimal.ZERO);
        detailVO.setActualParticipants(examStats.get("actualParticipants") != null ?
                new BigDecimal(examStats.get("actualParticipants").toString()) : BigDecimal.ZERO);
        detailVO.setAbsentCount(examStats.get("absentCount") != null ?
                new BigDecimal(examStats.get("absentCount").toString()) : BigDecimal.ZERO);
        detailVO.setQualified(examStats.get("qualified") != null ?
                new BigDecimal(examStats.get("qualified").toString()) : BigDecimal.ZERO);
        detailVO.setPassRate((BigDecimal) examStats.get("passRate"));
        detailVO.setAvgScore((BigDecimal) examStats.get("avgScore"));
        detailVO.setHighestScore(examStats.get("highestScore") != null ?
                new BigDecimal(examStats.get("highestScore").toString()) : BigDecimal.ZERO);
        detailVO.setLowestScore(examStats.get("lowestScore") != null ?
                new BigDecimal(examStats.get("lowestScore").toString()) : BigDecimal.ZERO);

        // 设置分数分布
        detailVO.setScoreDistribution(scoreDistribution);

        return detailVO;
    }
    //获取班级信息
    @Override
    public List<Map<String, Long>> getExamClass(String schoolNumber) {
        return testResultsMapper.getExamClass(schoolNumber);
    }
    //获取试卷信息
    @Override
    public List<Map<String, Long>> getExam(String classID) {
        return testResultsMapper.getExam(classID);
    }
//获取饼形图信息
    @Override
    public String getPieChart(String classID, String examId) {
        return testResultsMapper.getPieChart(classID,examId);
    }
//学生成绩查询
    @Override
    public List<StudentgradeinquiryVo> Studentgradeinquiry(String studentID) {
        return testResultsMapper.Studentgradeinquiry(studentID);
    }
//学生成绩查询详情
    @Override
    public ExamAndAnswerVO Studentresultsfordetails(String examId, String studentID) {
        ExamAndAnswerVO studentresultsfordetailsone = testResultsMapper.Studentresultsfordetails(examId, studentID);
        System.out.println("1    "+studentresultsfordetailsone);
        List<ExamAndAnswerlist> studentresultsfordetails =testResultsMapper.Studentresultsfordetailsone(examId, studentID);
        System.out.println("2    "+studentresultsfordetails);
        studentresultsfordetailsone.setExamAndAnswerlist(studentresultsfordetails);
        System.out.println("3    "+studentresultsfordetailsone);
        return studentresultsfordetailsone;
    }
//修改邮箱
    @Override
    public void updateEmail(String username, String password, String newEmail) {
        try {
            String plainPassword = decryptPassword(password);
            System.out.println("解密后的密码: " + plainPassword);
            if (!bCryptPasswordEncoder.matches(plainPassword,testResultsMapper.selectPasswordByUsername(username))) {
                throw new BusinessException(400, "密码错误");
            }
            Integer i =testResultsMapper.updateEmail(newEmail,username);
            if (i==0){
                throw new BusinessException(400, "修改邮箱失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException(400, "修改失败");
        }
    }
//修改密码
    @Override
    public void updatePassword(String username, String oldPassword, String newPassword) {
        try {
            String plainPassword = decryptPassword(oldPassword);
            System.out.println("解密后的旧密码: " + plainPassword);
            if (!bCryptPasswordEncoder.matches(plainPassword,testResultsMapper.selectPasswordByUsername(username))) {
                throw new BusinessException(400, "密码错误");
            }
            //解密新密码
            String ewPassword = decryptPassword(newPassword);
            System.out.println("解密后的新密码: " + ewPassword);
            String hashedPassword = bCryptPasswordEncoder.encode(ewPassword);
            System.out.println("加密后的新密码: " + hashedPassword);

            Integer i =testResultsMapper.updatePassword(username,hashedPassword);
            if (i==0){
                throw new BusinessException(400, "修改密码失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException(400, "修改失败");
        }
    }
    //获取该学生的错题本
    @Override
    public Map<String, Object> getMistakeCollection(String studentID, Integer pageNum, Integer pageSize, String searchContent, String status) {
        Map<String, Object> result = new HashMap<>();
        
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;
        
        // 查询错题列表
        List<StudentMistakeEntity> mistakeList = testResultsMapper.getMistakeCollection(
            studentID, offset, pageSize, searchContent, status
        );
        
        // 查询总记录数
        Integer total = testResultsMapper.getMistakeCollectionCount(studentID, searchContent, status);
        
        // 转换为ProcessedMistakeVO
        List<ProcessedMistakeVO> processedList = mistakeList.stream()
            .map(mistake -> {
                ProcessedMistakeVO vo = new ProcessedMistakeVO();
                vo.setMistake_id(mistake.getMistakeId());
                vo.setQuestionContent(mistake.getQuestionContent());
                vo.setStudentAnswers_string(mistake.getStudentAnswer());
                vo.setStandardAnswer(mistake.getStandardAnswer());
                vo.setMistakeTime(mistake.getMistakeTime());
                vo.setLastMistakeTime(mistake.getLastMistakeTime());
                vo.setStatus(mistake.getStatus());
                vo.setMistakeCount(mistake.getMistakeCount());
                return vo;
            })
            .collect(Collectors.toList());
            
        result.put("data", processedList);
        result.put("total", total);
        
        return result;
    }
//更新错题状态
    @Override
    public void updateMistakeStatus(Integer mistakeId, String status) {
        Integer i =testResultsMapper.updateMistakeStatus(mistakeId, status);
        if (i==0){
            throw new BusinessException(400, "更新状态失败");
        }
    }

    /**
     * 解密密码
     *
     * @param encryptedPassword 加密后的密码
     * @return 解密后的明文密码
     * @throws Exception 如果解密失败
     */
    private String decryptPassword(String encryptedPassword) throws Exception {
        return RSAUtil.decrypt(encryptedPassword, privateKey);
    }

    @Override
    public List<Map<String, Object>> getStudentClassInfo(String studentID) {
        if (studentID == null || studentID.trim().isEmpty()) {
            return null;
        }
        
        try {
            // 调用mapper查询班级信息
             List<Map<String, Object>> classInfo = testResultsMapper.getStudentClassInfo(studentID);
            
            // 如果没有查到数据，返回null
            if (classInfo == null || classInfo.isEmpty()) {
                return null;
            }
            
            return classInfo;
        } catch (Exception e) {
           e.printStackTrace();
            return null;
        }
    }
}
